0001 function [y,w,r]=nt_detrend(x,order,w0,basis,thresh,niter,wsize)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 nt_greetings;
0021
0022
0023 if nargin<2; error('!'); end
0024 if nargin<3; w0=[]; end
0025 if nargin<4||isempty(basis); basis='polynomials'; end
0026 if nargin<5||isempty(thresh); thresh=3; end
0027 if nargin<6||isempty(niter); niter=3; end
0028 if nargin<7; wsize=[]; end
0029
0030 if iscell(x)
0031 if ~isempty(w0); error('not implemented'); end
0032 y={}; w={}; r={};
0033 for iTrial=1:numel(x);
0034 [y{iTrial},w{iTrial},r{iTrial}]=nt_detrend(x{iTrial},order,w0,basis,thresh,niter,wsize);
0035 end
0036 return
0037 end
0038
0039 w=w0;
0040 if ~isempty(w)
0041 w=w(:);
0042 if numel(w)<size(x,1)
0043
0044 idx=w;
0045 w=zeros(size(x,1),1);
0046 w(idx)=1;
0047 end
0048 end
0049
0050 if isempty(wsize) || ~wsize
0051
0052 [y,w,r]=nt_detrend_helper(x,order,w,basis,thresh,niter);
0053 else
0054 wsize=2*floor(wsize/2);
0055
0056
0057 if numel(order)>1; error('!'); end
0058 if ~isempty(w) && ~(size(w,1)==size(x,1)) ; disp(size(w)); error('!'); end
0059 if ~(isempty(basis) || isstring(basis) || ~(isnumeric(basis)&&size(basis,1)==size(x,1))); error('!'); end
0060 if thresh==0; error('thresh=0 is not what you want...'); end
0061 if numel(thresh)>1; error('!'); end
0062 if numel(niter)>1; error('!'); end
0063
0064 dims=size(x); nchans=dims(2);
0065 x=x(:,:);
0066 w=w(:,:);
0067 if isempty(w); w=ones(size(x)); end
0068 if size(w,2)==1; w=repmat(w,1,size(x,2)); end
0069
0070
0071
0072
0073
0074 for iIter=1:niter
0075
0076 y=zeros(size(x));
0077 trend=zeros(size(x));
0078 a=zeros(size(x,1),1);
0079
0080
0081
0082 offset=0;
0083 while true
0084 start=offset+1;
0085 stop=min(size(x,1),offset+wsize);
0086
0087
0088 counter=5;
0089 while any (sum(min(w(start:stop),2))) <wsize
0090 if counter <= 0 ; break; end
0091 start=max(1,start-wsize/2);
0092 stop=min(size(x,1),stop+wsize/2);
0093 counter=counter-1;
0094 end
0095 if rem(stop-start+1,2)==1; stop=stop-1; end
0096 wsize2=stop-start+1;
0097
0098
0099 NITER=1;
0100 yy=nt_detrend_helper(x(start:stop,:),order,w(start:stop,:),basis,thresh,NITER);
0101
0102
0103 if start==1
0104 b=[ones(1,wsize2/2)*wsize2/2, wsize2/2:-1:1]';
0105 elseif stop==size(x,1)
0106 b=[1:wsize2/2, ones(1,wsize2/2)*wsize2/2]';
0107 else
0108 b=[1:wsize2/2, wsize2/2:-1:1]';
0109 end
0110
0111
0112 y(start:stop,:)=y(start:stop,:)+bsxfun(@times,yy,b);
0113 trend(start:stop,:)=trend(start:stop,:)+bsxfun(@times,x(start:stop,:)-yy,b);
0114
0115 a(start:stop,1)=a(start:stop)+b;
0116
0117 offset=offset+wsize/2;
0118 if offset>size(x,1)-wsize/2; break; end
0119 end
0120
0121 if stop<size(x,1); y(end,:)=y(end-1,:); a(end,:)=a(end-1,:); end;
0122
0123 y=bsxfun(@times,y,1./a); y(find(isnan(y)))=0;
0124 trend=bsxfun(@times,trend,1./a); trend(find(isnan(trend)))=0;
0125
0126
0127 d=x-trend;
0128
0129
0130 if ~isempty(w); d=bsxfun(@times,d,w); end
0131 ww=ones(size(x));
0132 ww(find(abs(d)>thresh*repmat(std(d),size(x,1),1))) = 0;
0133 clear d
0134
0135
0136 if isempty(w);
0137 w=ww;
0138 else
0139 w=min(w,ww);
0140 end
0141 clear ww;
0142
0143 end
0144
0145 w=[];r=[];
0146
0147 end
0148
0149 if ~nargout
0150
0151 subplot 411; plot(x); title('raw'); xlim([1,size(x,1)])
0152 subplot 412; plot(y); title('detrended'); xlim([1,size(x,1)])
0153 subplot 413; plot(x-y); title('trend'); xlim([1,size(x,1)])
0154 subplot 414; nt_imagescc(w'); title('weight');
0155 clear y w r
0156 end
0157 end
0158
0159
0160 function [y,w,r]=nt_detrend_helper(x,order,w,basis,thresh,niter)
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 nt_greetings;
0195
0196
0197 if nargin<2; error('!'); end
0198 if nargin<3; w=[]; end
0199 if nargin<4||isempty(basis); basis='polynomials'; end
0200 if nargin<5||isempty(thresh); thresh=3; end
0201 if nargin<6||isempty(niter); niter=3; end
0202
0203 if thresh==0; error('thresh=0 is not what you want...'); end
0204
0205 dims=size(x);
0206 x=x(:,:);
0207 w=w(:,:);
0208
0209 if size(w,2)==1; w=repmat(w,1,size(x,2)); end
0210
0211
0212 if isnumeric(basis)
0213 r=basis;
0214 else
0215 switch basis
0216 case 'polynomials'
0217 r=zeros(size(x,1),numel(order));
0218 lin=linspace(-1,1,size(x,1));
0219 for k=1:order
0220 r(:,k)=lin.^k;
0221 end
0222 case 'sinusoids'
0223 r=zeros(size(x,1),numel(order)*2);
0224 lin=linspace(-1,1,size(x,1));
0225 for k=1:order
0226 r(:,2*k-1)=sin(2*pi*k*lin/2);
0227 r(:,2*k)=cos(2*pi*k*lin/2);
0228 end
0229 otherwise
0230 error('!');
0231 end
0232 end
0233
0234
0235
0236
0237
0238
0239 for iIter=1:niter
0240
0241
0242 [~,y]=nt_regw(x,r,w);
0243
0244
0245 d=x-y;
0246 if ~isempty(w); d=bsxfun(@times,d,w); end
0247 ww=ones(size(x));
0248 ww(find(abs(d)>thresh*repmat(std(d),size(x,1),1))) = 0;
0249
0250
0251 if isempty(w);
0252 w=ww;
0253 else
0254 w=min(w,ww);
0255 end
0256 clear ww;
0257 end
0258 y=x-y;
0259 y=reshape(y,dims);
0260 w=reshape(w,dims);
0261
0262 end
0263
0264
0265 function test_me
0266 if 0
0267
0268 x=(1:100)'; x=x+ randn(size(x));
0269 WSIZE=30;
0270 y=nt_detrend2(x,1,[],[],[],[],WSIZE);
0271 figure(1); clf; plot([x,y]);
0272 end
0273 if 0
0274
0275 x=(1:100)'; x=x+ randn(size(x));
0276 x(40:50)=0;
0277 WSIZE=30;
0278 [yy,ww]=nt_detrend2(x,1,[],[],2,[],WSIZE);
0279 [y,w]=nt_detrend(x,1);
0280 figure(1); clf; subplot 211;
0281 plot([x,y,yy]);
0282 subplot 212; plot([w,ww],'.-');
0283 end
0284 if 0
0285
0286 x=cumsum(randn(1000,1)+0.1);
0287 WSIZE=200;
0288 [y1,w1]=nt_detrend(x,1,[]);
0289 [y2,w2]=nt_detrend2(x,1,[],[],[],[],WSIZE);
0290 figure(1); clf;
0291 plot([x,y1,y2]); legend('before', 'after');
0292 end
0293 if 0
0294
0295 x=linspace(0,100,1000)';
0296 x=x+3*randn(size(x));
0297 x(1:100,:)=100;
0298 w=ones(size(x)); w(1:100,:)=0;
0299 y=nt_detrend2(x,3,[],[],[],[],WSIZE);
0300 yy=nt_detrend2(x,3,w,[],[],[],WSIZE);
0301 figure(1); clf; plot([x,y,yy]); legend('before', 'unweighted','weighted');
0302 end
0303 if 0
0304 [p,x]=nt_read_data('/data/meg/theoldmanandthesea/eeg/mc/MC_aespa_speech_43.mat'); x=x'; x=x(:,1:128);
0305
0306
0307 x=nt_demean(x);
0308 figure(1);
0309 nt_detrend(x,3);
0310 figure(2);
0311 WSIZE=1000;
0312 nt_detrend2(x(:,:),3,[],[],[],[],WSIZE);
0313 end
0314 end
0315
0316